package com.domain.common.http;

import com.domain.common.signature.Signature;
import okhttp3.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.net.ssl.*;
import java.io.File;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * ClassName: OkHttp<br>
 * Description: http 请求工具类 采用.OkHttp实现<br>
 * Reason: TODO ADD REASON(可选) <br>
 *
 * @author Sean
 * @date: 2016年8月29日 下午6:30:47
 * @version V1.0
 * @since JDK 1.8
 */
public class OkHttp {
	private static final Log logger = LogFactory.getLog(OkHttp.class);
	static X509TrustManager x509TrustManager = new X509TrustManager() {

		@Override
		public X509Certificate[] getAcceptedIssuers() {
			X509Certificate[] certificates = new X509Certificate[0];
			return certificates;
		}

		@Override
		public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {

		}

		@Override
		public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {

		}
	};
	static SSLContext sslContext = null;
	static {
		try {
			sslContext = SSLContext.getInstance("SSL", "SunJSSE");
			sslContext.init(null, new TrustManager[] { x509TrustManager }, new SecureRandom());
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (NoSuchProviderException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	static HostnameVerifier hostnameVerifier = new HostnameVerifier() {

		@Override
		public boolean verify(String hostname, SSLSession session) {
			return true;
		}
	};
	private static final OkHttpClient CLIENT = new OkHttpClient().newBuilder().connectTimeout(200, TimeUnit.SECONDS)
			.sslSocketFactory(sslContext.getSocketFactory(), x509TrustManager).hostnameVerifier(hostnameVerifier)
			.build();
	private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
	private static final MediaType TEXT = MediaType.parse("application/text; charset=utf-8");
	public static final MediaType MEDIA_TYPE_MARKDOWN= MediaType.parse("text/x-markdown; charset=utf-8");
	  public static final MediaType STREAM = MediaType.parse("application/octet-stream");  

	/**
	 * GET请求
	 * 
	 * @param url
	 * @return
	 * @throws IOException
	 */
	public static String get(String url) throws IOException {
		Request request = new Request.Builder().url(url).build();
		Response response = CLIENT.newCall(request).execute();
		logger.info(url);
		logger.info(request);
		logger.info(response);
		if (response.isSuccessful()) {
			return response.body().string();
		}
		return null;
	}

	/**
	 * GET请求
	 * 
	 * @param url
	 * @param map
	 * @return
	 * @throws IOException
	 */
	public static String get(String url, Map<String, String> map) throws IOException {
		map = Signature.signMap(map);
		StringBuilder sb = new StringBuilder();
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (null != entry.getValue() && !"".equals(entry.getValue())) {
				if (sb.length() > 0) {
					sb.append("&");
				}
				sb.append(entry.getKey());
				sb.append("=");
				sb.append(URLEncoder.encode(entry.getValue(), "UTF-8"));
			}
		}
		if (sb.length() > 0) {
			url = url + "?" + sb.toString();
		}
		Request request = new Request.Builder().url(url).build();
		Response response = CLIENT.newCall(request).execute();
		logger.info(url);
		logger.info(request);
		logger.info(response);
		if (response.isSuccessful()) {
			return response.body().string();
		}
		return null;
	}

	/**
	 * POST提交
	 * 
	 * @param url
	 * @param content
	 * @return
	 * @throws IOException
	 */
	public static String postByText(String url, String content) throws IOException {
		RequestBody body = RequestBody.create(TEXT, content);
		Request request = new Request.Builder().url(url).post(body).build();
		Response response = CLIENT.newCall(request).execute();
		logger.info(url);
		logger.info(request);
		logger.info(response);
		if (response.isSuccessful()) {
			return response.body().string();
		}
		return null;
	}

	/**
	 * POST提交键值对
	 * 
	 * @param url
	 * @param map
	 * @return
	 * @throws IOException
	 */
	public static String postByMap(String url, Map<String, String> map) throws IOException {
		FormBody.Builder builder = new FormBody.Builder();
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (entry.getValue() != "") {
				builder.addEncoded(entry.getKey(), entry.getValue());
			}
		}
		RequestBody body = builder.build();
		Request request = new Request.Builder().url(url).post(body).build();
		Response response = CLIENT.newCall(request).execute();
		logger.info(url);
		logger.info(request);
		logger.info(response);
		if (response.isSuccessful()) {
			return response.body().string();
		}
		return null;
	}

	public static String signPostByMap(String url, Map<String, String> map) throws IOException {
		map = Signature.signMap(map);
		FormBody.Builder builder = new FormBody.Builder();
		for (Map.Entry<String, String> entry : map.entrySet()) {
			if (entry.getValue() != "") {
				builder.addEncoded(entry.getKey(), entry.getValue());
			}
		}
		RequestBody body = builder.build();
		Request request = new Request.Builder().url(url).post(body).build();
		Response response = CLIENT.newCall(request).execute();
		logger.info(url);
		logger.info(request);
		logger.info(response);
		if (response.isSuccessful()) {
			return response.body().string();
		}
		return null;
	}

	/**
	 * POST提交Json数据
	 * 
	 * @param url
	 * @param content
	 * @return
	 * @throws IOException
	 */
	public static String postByJson(String url, String content) throws IOException {
		RequestBody body = RequestBody.create(JSON, content);
		Request request = new Request.Builder().url(url).post(body).build();
		Response response = CLIENT.newCall(request).execute();
		logger.info(url);
		logger.info(request);
		logger.info(response);
		if (response.isSuccessful()) {
			return response.body().string();
		}
		return null;
	}
	
	/**
	 * POST提交File
	 * 
	 * @param url
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static String postByFile(String url,File file) throws IOException{
		 Request request = new Request.Builder()
			        .url(url)
			        .post(RequestBody.create(MEDIA_TYPE_MARKDOWN, file))
			        .build();			 
			    Response response = CLIENT.newCall(request).execute();
			    if (response.isSuccessful()) {
					return response.body().string();
				}
				return null;
	}
	
	/**
	 * POST提交流
	 * 
	 * @param url
	 * @param file
	 * @return
	 * @throws IOException
	 */
	public static String postByStream(String url,byte[] bt) throws IOException{
		 Request request = new Request.Builder()
			        .url(url)
			        .post(RequestBody.create(STREAM,bt))
			        .build();			 
			    Response response = CLIENT.newCall(request).execute();
			    logger.info(url);
				logger.info(request);
				logger.info(response);
			    if (response.isSuccessful()) {
					return response.body().string();
				}
				return null;
	}
}
